package com.ruoyi.app.service.impl

import cn.hutool.core.bean.BeanUtil
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.kotlin.KtUpdateWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.baomidou.shaun.core.context.ProfileHolder
import com.ruoyi.app.common.*
import com.ruoyi.app.domain.dto.MessageSearchDto
import com.ruoyi.app.domain.vo.InteractionMessageVo
import com.ruoyi.app.domain.vo.MemberMessageVo
import com.ruoyi.app.domain.vo.MessageIndexVo
import com.ruoyi.app.domain.vo.SystemMessageVo
import com.ruoyi.app.service.MessageApiService
import com.ruoyi.back.domain.UserInteractionMessage
import com.ruoyi.back.domain.UserMemberNoticeMessage
import com.ruoyi.back.domain.UserSystemNoticeMessage
import com.ruoyi.back.enums.MessageTypeEnum
import com.ruoyi.back.service.*
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

@Service
class MessageApiServiceImpl : MessageApiService {

    @Autowired
    private lateinit var userMemberMessageService: UserMemberMessageService

    @Autowired
    private lateinit var userSystemNoticeMessageService: UserSystemNoticeMessageService

    @Autowired
    private lateinit var userInteractionMessageService: UserInteractionMessageService

    @Autowired
    private lateinit var appUserService: AppUserService

    @Autowired
    private lateinit var templateService: TemplateService


    override fun userMessageIndex(messageSearchDto: MessageSearchDto): Data<MessageIndexVo> {

        return Ok("获取用户消息列表成功", kotlin.run {
            messageSearchDto.type?.run {
                when (this) {
                    1 -> {
                        MessageIndexVo().apply {
                            systemMessage = userSystemNoticeMessageService.page(
                                Page(messageSearchDto.pageNum!!.toLong(), messageSearchDto.pageSize!!.toLong()),
                                KtQueryWrapper(UserSystemNoticeMessage::class.java)
                                    .eq(UserSystemNoticeMessage::createBy, ProfileHolder.getProfile().id.toLong())
                                    .orderByDesc(UserSystemNoticeMessage::createTime)
                            )
                                .let { page ->
                                    Page<SystemMessageVo>().apply {
                                        BeanUtil.copyProperties(page, this)
                                        records = page.records.takeIf { it.isNotEmpty() }
                                            ?.run {
                                                map {
                                                    SystemMessageVo().apply {
                                                        BeanUtil.copyProperties(it, this)
                                                        createDate = it.createTime?.format()
                                                    }
                                                }
                                            }
                                    }.format()
                                }
                        }
                    }

                    2 -> {
                        MessageIndexVo().apply {
                            memberMessage = userMemberMessageService.page(
                                Page(messageSearchDto.pageNum!!.toLong(), messageSearchDto.pageSize!!.toLong()),
                                KtQueryWrapper(UserMemberNoticeMessage::class.java)
                                    .eq(UserMemberNoticeMessage::createBy, ProfileHolder.getProfile().id.toLong())
                                    .orderByDesc(UserMemberNoticeMessage::createTime)
                            )
                                .let { page ->
                                    Page<MemberMessageVo>().apply {
                                        BeanUtil.copyProperties(page, this)
                                        records = page.records.takeIf { it.isNotEmpty() }
                                            ?.run {
                                                map {
                                                    MemberMessageVo().apply {
                                                        BeanUtil.copyProperties(it, this)
                                                        noticeType = it.noticeType?.noticeType()
                                                        createDate = it.createTime?.format()
                                                    }
                                                }
                                            }
                                    }.format()
                                }
                        }
                    }

                    3 -> {
                        MessageIndexVo()
                    }

                    4 -> {
                        MessageIndexVo().apply {
                            interactionMessage = userInteractionMessageService.page(
                                Page(messageSearchDto.pageNum!!.toLong(), messageSearchDto.pageSize!!.toLong()),
                                KtQueryWrapper(UserInteractionMessage::class.java)
                                    .eq(UserInteractionMessage::createBy, ProfileHolder.getProfile().id.toLong())
                                    .orderByDesc(UserInteractionMessage::createTime)
                            )
                                .let { page ->
                                    Page<InteractionMessageVo>().apply {
                                        BeanUtil.copyProperties(page, this)
                                        records = page.records.takeIf { it.isNotEmpty() }
                                            ?.run {
                                                map {
                                                    InteractionMessageVo().apply {
                                                        appUserService.appUserInfo(it.sendUser!!)?.let {
                                                            headUrl = it.headUrl
                                                            username = it.username
                                                        }
                                                        templateService.getById(it.templateId)?.let { template ->
                                                            templateContent = template.content
                                                            tipContent = when (template.type) {
                                                                MessageTypeEnum.LIKE.code -> "${it.type?.messageType()}了你的${template.type?.templateType()}"
                                                                MessageTypeEnum.COLLECT.code -> "${it.type?.messageType()}了你的${template.type?.templateType()}"
                                                                MessageTypeEnum.COMMENT.code -> "${it.type?.messageType()}了你: ${it.comment}"
                                                                else -> "未知"
                                                            }
                                                        }
                                                        id = it.id
                                                        createDate = it.createTime?.format()
                                                    }
                                                }
                                            }
                                    }.format()
                                }
                        }
                    }

                    else -> {
                        MessageIndexVo()
                    }
                }

            } ?: kotlin.run {
                MessageIndexVo().apply {
                    systemMessage = userSystemNoticeMessageService.page(
                        Page(messageSearchDto.pageNum!!.toLong(), messageSearchDto.pageSize!!.toLong()),
                        KtQueryWrapper(UserSystemNoticeMessage::class.java)
                            .eq(UserSystemNoticeMessage::createBy, ProfileHolder.getProfile().id.toLong())
                            .orderByDesc(UserSystemNoticeMessage::createTime)
                    )
                        .let { page ->
                            Page<SystemMessageVo>().apply {
                                BeanUtil.copyProperties(page, this)
                                records = page.records.takeIf { it.isNotEmpty() }
                                    ?.run {
                                        map {
                                            SystemMessageVo().apply {
                                                BeanUtil.copyProperties(it, this)
                                                createDate = it.createTime?.format()
                                            }
                                        }
                                    }
                            }.format()
                        }

                    memberMessage = userMemberMessageService.page(
                        Page(messageSearchDto.pageNum!!.toLong(), messageSearchDto.pageSize.toLong()),
                        KtQueryWrapper(UserMemberNoticeMessage::class.java)
                            .eq(UserMemberNoticeMessage::createBy, ProfileHolder.getProfile().id.toLong())
                            .orderByDesc(UserMemberNoticeMessage::createTime)
                    )
                        .let { page ->
                            Page<MemberMessageVo>().apply {
                                BeanUtil.copyProperties(page, this)
                                records = page.records.takeIf { it.isNotEmpty() }
                                    ?.run {
                                        map {
                                            MemberMessageVo().apply {
                                                BeanUtil.copyProperties(it, this)
                                                noticeType = it.noticeType?.noticeType()
                                                createDate = it.createTime?.format()
                                            }
                                        }
                                    }
                            }.format()
                        }
                    interactionMessage = userInteractionMessageService.page(
                        Page(messageSearchDto.pageNum!!.toLong(), messageSearchDto.pageSize.toLong()),
                        KtQueryWrapper(UserInteractionMessage::class.java)
                            .eq(UserInteractionMessage::createBy, ProfileHolder.getProfile().id.toLong())
                            .orderByDesc(UserInteractionMessage::createTime)
                    )
                        .let { page ->
                            Page<InteractionMessageVo>().apply {
                                BeanUtil.copyProperties(page, this)
                                records = page.records.takeIf { it.isNotEmpty() }
                                    ?.run {
                                        map {
                                            InteractionMessageVo().apply {
                                                appUserService.appUserInfo(it.sendUser!!)?.let {
                                                    headUrl = it.headUrl
                                                    username = it.username
                                                }
                                                templateService.getById(it.templateId)?.let { template ->
                                                    templateContent = template.content
                                                    tipContent = when (template.type) {
                                                        MessageTypeEnum.LIKE.code -> "${it.type?.messageType()}了你的${template.type?.templateType()}"
                                                        MessageTypeEnum.COLLECT.code -> "${it.type?.messageType()}了你的${template.type?.templateType()}"
                                                        MessageTypeEnum.COMMENT.code -> "${it.type?.messageType()}了你: ${it.comment}"
                                                        else -> "未知"
                                                    }
                                                }
                                                id = it.id
                                                createDate = it.createTime?.format()
                                            }
                                        }
                                    }
                            }.format()
                        }
                }
            }
        })
    }

    override fun getUnReadMessageCount(userId: Long): Int =
        userMemberMessageService.count(
            KtQueryWrapper(UserMemberNoticeMessage::class.java)
                .eq(UserMemberNoticeMessage::createBy, userId)
                .eq(UserMemberNoticeMessage::isRead, false)
        )
            .plus(
                userSystemNoticeMessageService.count(
                    KtQueryWrapper(UserSystemNoticeMessage::class.java)
                        .eq(UserSystemNoticeMessage::createBy, userId)
                        .eq(UserSystemNoticeMessage::isRead, false)
                )
            )
            .plus(
                userInteractionMessageService.count(
                    KtQueryWrapper(UserInteractionMessage::class.java)
                        .eq(UserInteractionMessage::createBy, userId)
                        .eq(UserInteractionMessage::isRead, false)
                )
            )

    override fun getMessageDetail(id: Long): Data<SystemMessageVo> =
        Ok("获取消息详情成功", userSystemNoticeMessageService.getById(id)?.let {
            SystemMessageVo().apply {
                BeanUtil.copyProperties(it, this)
                createDate = it.createTime?.format()
            }
        })

    override fun readSystemMessage(id: Long?): Data<Boolean> =
        id?.run {
            userSystemNoticeMessageService.getById(id)?.run {
                Ok("已读成功", userSystemNoticeMessageService.updateById(this.apply {
                    isRead = true
                }))
            } ?: Fail("不存在该资源")
        } ?: kotlin.run {
            Ok("一键已读成功", userSystemNoticeMessageService.list(
                KtQueryWrapper(UserSystemNoticeMessage::class.java)
                    .eq(UserSystemNoticeMessage::createBy, ProfileHolder.getProfile().id.toLong())
                    .eq(UserSystemNoticeMessage::isRead, false)
            )
                .takeIf { it.isNotEmpty() }
                ?.run {
                    userSystemNoticeMessageService.updateBatchById(map {
                        it.apply {
                            isRead = true
                        }
                    })
                })
        }

    override fun readMemberMessage(id: Long?): Data<Boolean> =
        id?.run {
            userMemberMessageService.getById(id)?.run {
                Ok("已读成功", userMemberMessageService.updateById(this.apply {
                    isRead = true
                }))
            } ?: Fail("不存在该资源")
        } ?: kotlin.run {
            Ok("一键已读成功", userMemberMessageService.list(
                KtQueryWrapper(UserMemberNoticeMessage::class.java)
                    .eq(UserMemberNoticeMessage::createBy, ProfileHolder.getProfile().id.toLong())
                    .eq(UserMemberNoticeMessage::isRead, false)
            )
                .takeIf { it.isNotEmpty() }
                ?.run {
                    userMemberMessageService.updateBatchById(map {
                        it.apply {
                            isRead = true
                        }
                    })
                })
        }

    override fun readInteractionMessage(id: Long?): Data<Boolean> =
        id?.run {
            userInteractionMessageService.getById(id)?.run {
                Ok("已读成功", userInteractionMessageService.updateById(this.apply {
                    isRead = true
                }))
            } ?: Fail("不存在该资源")
        } ?: kotlin.run {
            Ok("一键已读成功", userInteractionMessageService.list(
                KtQueryWrapper(UserInteractionMessage::class.java)
                    .eq(UserInteractionMessage::createBy, ProfileHolder.getProfile().id.toLong())
                    .eq(UserInteractionMessage::isRead, false)
            )
                .takeIf { it.isNotEmpty() }
                ?.run {
                    userInteractionMessageService.updateBatchById(map {
                        it.apply {
                            isRead = true
                        }
                    })
                })
        }

    override fun removeSystemMessage(id: Long?): Data<Boolean> =
        id?.run {
            Ok("移除成功", userSystemNoticeMessageService.removeById(id))
        } ?: kotlin.run {
            Ok(
                "全部清空成功", userSystemNoticeMessageService.remove(
                    KtUpdateWrapper(UserSystemNoticeMessage::class.java)
                        .eq(UserSystemNoticeMessage::createBy, ProfileHolder.getProfile().id.toLong())
                )
            )
        }

    override fun removeMemberMessage(id: Long?): Data<Boolean> =
        id?.run {
            Ok("移除成功", userMemberMessageService.removeById(id))
        } ?: kotlin.run {
            Ok(
                "全部清空成功", userMemberMessageService.remove(
                    KtUpdateWrapper(UserMemberNoticeMessage::class.java)
                        .eq(UserMemberNoticeMessage::createBy, ProfileHolder.getProfile().id.toLong())
                )
            )
        }

    override fun removeInteractionMessage(id: Long?): Data<Boolean> =
        id?.run {
            Ok("移除成功", userInteractionMessageService.removeById(id))
        } ?: kotlin.run {
            Ok(
                "全部清空成功", userInteractionMessageService.remove(
                    KtUpdateWrapper(UserInteractionMessage::class.java)
                        .eq(UserInteractionMessage::createBy, ProfileHolder.getProfile().id.toLong())
                )
            )
        }
}